package com.ehome.poct.base.dao.banner.repository;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ehome.poct.base.api.dto.banner.*;
import com.ehome.poct.base.api.vo.banner.*;
import com.ehome.poct.base.dao.banner.entity.TestBannerExposureDO;
import com.ehome.poct.base.dao.banner.entity.TestConfBannerDO;
import com.ehome.poct.base.dao.mapping.BannerMapping;
import com.ehome.poct.base.dao.banner.mapper.BannerMapper;
import com.ehome.poct.base.dao.banner.mapper.TestBannerExposureMapper;
import com.ehome.poct.base.banner.repository.BannerRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * @author muqiu
 * @date 2022/03/02 14:15
 */
@Repository
public class BannerRepositoryImpl  implements BannerRepository {
    @Autowired private BannerMapper bannerMapper;
    @Autowired private BannerMapping bannerMapping;
    @Autowired private TestBannerExposureMapper testBannerExposureMapper;

    @Override
    public List<BannerVO> list(Integer deviceType) {
            var banners = Optional.ofNullable(bannerMapper.selectList(Wrappers.<TestConfBannerDO>lambdaQuery()
                    .eq(TestConfBannerDO::getDeviceType,deviceType)
                    .le(TestConfBannerDO::getEffectTime, LocalDateTime.now())
                    .ge(TestConfBannerDO::getInvalidTime,LocalDateTime.now())
                    .ne(TestConfBannerDO::getStatus,3)
                    .orderByDesc(TestConfBannerDO::getImgOrder)
                    .orderByDesc(TestConfBannerDO::getCreateTime))).orElse(null);
            var list = new ArrayList<BannerVO>();
            banners.forEach(c -> list.add(new BannerVO(c.getImgUrl(), c.getBannerItemId())));
            return list;
    }

    @Override
    public void incrExposureById(BannerExposureDTO dto) {
        var testConfBanner = new TestConfBannerDO().selectById(dto.getId());
        if(!testConfBanner.getUpdateTime().toLocalDate().isEqual(LocalDate.now())){
            TestBannerExposureDO testBannerExposureDO = new TestBannerExposureDO(null, dto.getId(), testConfBanner.getUpdateTime().toLocalDate(), testConfBanner.getExposureToday());
            testBannerExposureDO.setDelete(false);
            testBannerExposureDO.insert();
            testConfBanner.setExposureToday((long)0);
        }
        testConfBanner.setExposureToday(testConfBanner.getExposureToday() + dto.getExposureTimes());
        testConfBanner.setExposureTotal(testConfBanner.getExposureTotal() + dto.getExposureTimes());
        bannerMapper.updateById(testConfBanner);
    }

    @Override
    public Boolean add(BannerDTO bannerDTO) {
        TestConfBannerDO testConfBannerDO = new TestConfBannerDO();
        BeanUtils.copyProperties(bannerDTO,testConfBannerDO);
        if(testConfBannerDO.getEffectTime().isBefore(LocalDateTime.now()) && testConfBannerDO.getInvalidTime().isAfter(LocalDateTime.now())){
            testConfBannerDO.setStatus(0);
        }
        if(testConfBannerDO.getEffectTime().isAfter(LocalDateTime.now())){
            testConfBannerDO.setStatus(1);
        }
        if(testConfBannerDO.getInvalidTime().isBefore(LocalDateTime.now())){
            testConfBannerDO.setStatus(2);
        }
        testConfBannerDO.setDelete(false);
        if(null != testConfBannerDO.getBannerItemId()){
            return bannerMapper.updateById(testConfBannerDO) > 0;
        }
        testConfBannerDO.setBannerItemId(IdWorker.getId());
        //如果没有排序号则默认为id
        if(bannerDTO.getImgOrder() == null){
            testConfBannerDO.setImgOrder(testConfBannerDO.getBannerItemId());
        }
        return bannerMapper.insert(testConfBannerDO) > 0;
    }

    @Override
    public List<BannerDictDataVO> getDictData() {
        var bannerInfoVO = new ArrayList<BannerDictDataVO>();
        //设备类型数据字典
        var deviceType =  bannerMapper.getDictData("sys_device_type");
        bannerInfoVO.add(new BannerDictDataVO("deviceType",deviceType));
        //广告状态
        var bannerStatus =  bannerMapper.getDictData("sys_banner_status");
        bannerInfoVO.add(new BannerDictDataVO("bannerStatus",bannerStatus));
        //广告位置
        var bannerPosition =  bannerMapper.getDictData("sys_banner_position");
        bannerInfoVO.add(new BannerDictDataVO("bannerPosition",bannerPosition));
        return bannerInfoVO;
    }

    @Override
    public BannerInfoPageVO getBanners(BannerPageDTO bannerPageDTO) {
         var page = bannerMapper.selectPage(new Page<>(bannerPageDTO.getPageIndex(), bannerPageDTO.getPageSize()), Wrappers.<TestConfBannerDO>lambdaQuery()
                .eq(StringUtils.checkValNotNull(bannerPageDTO.getDeviceType()),TestConfBannerDO::getDeviceType, bannerPageDTO.getDeviceType()).like(StringUtils.checkValNotNull(bannerPageDTO.getBannerName()),TestConfBannerDO::getBannerName, bannerPageDTO.getBannerName())
                .eq(StringUtils.checkValNotNull(bannerPageDTO.getBannerPosition()),TestConfBannerDO::getBannerPosition, bannerPageDTO.getBannerPosition()).eq(StringUtils.checkValNotNull(bannerPageDTO.getStatus()),TestConfBannerDO::getStatus, bannerPageDTO.getStatus())
                .and(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()) && StringUtils.checkValNotNull(bannerPageDTO.getEffectTime()),i -> i.le(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()),TestConfBannerDO::getEffectTime, bannerPageDTO.getInvalidTime()).ge(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()),TestConfBannerDO::getInvalidTime, bannerPageDTO.getInvalidTime()))
                 .or(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()) && StringUtils.checkValNotNull(bannerPageDTO.getEffectTime()),i -> i.le(StringUtils.checkValNotNull(bannerPageDTO.getEffectTime()),TestConfBannerDO::getEffectTime, bannerPageDTO.getEffectTime()).ge(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()),TestConfBannerDO::getInvalidTime, bannerPageDTO.getEffectTime()))
                 .or(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()) && StringUtils.checkValNotNull(bannerPageDTO.getEffectTime()),i -> i.ge(StringUtils.checkValNotNull(bannerPageDTO.getEffectTime()),TestConfBannerDO::getEffectTime, bannerPageDTO.getInvalidTime()).le(StringUtils.checkValNotNull(bannerPageDTO.getInvalidTime()),TestConfBannerDO::getInvalidTime, bannerPageDTO.getInvalidTime()))
                .orderByDesc(TestConfBannerDO::getCreateTime));
         //更新广告状态
             page.getRecords().forEach(c -> {
             if(c.getEffectTime().isBefore(LocalDateTime.now()) && c.getStatus() == 1){
                 c.setStatus(0);
                 bannerMapper.updateById(c);
             }
             if(c.getInvalidTime().isBefore(LocalDateTime.now()) && (c.getStatus() == 0 || c.getStatus() == 1)){
                 c.setStatus(2);
                 bannerMapper.updateById(c);
             }
         });
         page.getRecords().forEach(r -> r.setDictData(testBannerExposureMapper));
         return new BannerInfoPageVO((int)page.getTotal(),bannerMapping.toBannerInfoVOList(page.getRecords()));
    }

    @Override
    public BannerInfoVO getById(Long id) {
        var banner = bannerMapper.selectById(id);
        banner.setDictData(testBannerExposureMapper);
        return bannerMapping.to(banner);
    }

    @Override
    public Boolean disable(BannerAbleDTO ableDTO) {
        var testConfBannerDO = bannerMapper.selectById(ableDTO.getId());
        if(null != testConfBannerDO && ableDTO.getType() == 0){
            testConfBannerDO.setStatus(3);
        }else if(null != testConfBannerDO && ableDTO.getType() == 1) {
            testConfBannerDO.setStatus(1);
        }else {
            return false;
        }
        return bannerMapper.updateById(testConfBannerDO) > 0;
    }

    @Override
    public Boolean delete(Long id) {
        return bannerMapper.deleteById(id) > 0;
    }

    @Override
    public BannerDataVO getData(BannerDataDTO bannerDataDTO) {
        var testConfBannerDO = bannerMapper.selectById(bannerDataDTO.getBannerItemId());
        var bannerDataVO = new BannerDataVO();
        testConfBannerDO.setDictData(testBannerExposureMapper);
        BeanUtils.copyProperties(testConfBannerDO,bannerDataVO);
        LocalDate time = bannerDataDTO.getStartTime();
        //曝光数据
        ArrayList<Long> datas = new ArrayList<>();
        while (!bannerDataDTO.getEndTime().isBefore(time)){
            Long exposure = testBannerExposureMapper.getExposure(bannerDataDTO.getBannerItemId(),time);
            datas.add(exposure == null ? 0 : exposure);
            time = time.plusDays(1);
        }
        bannerDataVO.setExposureData(datas);
        return bannerDataVO;
    }
}
